home *** CD-ROM | disk | FTP | other *** search
- #undef OLD_WAY
- /*
- * text.c - text output processing portion of nroff word processor
- *
- * adapted for atariST/TOS by Bill Rosenkranz 11/89
- * net: rosenkra@hall.cray.com
- * CIS: 71460,17
- * GENIE: W.ROSENKRANZ
- *
- * original author:
- *
- * Stephen L. Browning
- * 5723 North Parker Avenue
- * Indianapolis, Indiana 46220
- *
- * history:
- *
- * - Originally written in BDS C;
- * - Adapted for standard C by W. N. Paul
- * - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
- */
-
- #undef NRO_MAIN /* extern globals */
-
- #include <stdio.h>
- #include "nroff.h"
-
-
- /*------------------------------*/
- /* text */
- /*------------------------------*/
- text (p)
- register char *p;
- {
-
- /*
- * main text processing
- */
-
- register int i;
- char wrdbuf[MAXLINE];
-
-
- /*
- * skip over leading blanks if in fill mode. we indent later.
- * since leadbl does a robrk, do it if in .nf mode
- */
- if (dc.fill == YES)
- {
- if (*p == ' ' || *p == '\n' || *p == '\r')
- leadbl (p);
- }
- else
- robrk ();
-
-
- /*
- * expand escape sequences
- */
- expesc (p, wrdbuf);
-
-
- /*
- * test for how to output
- */
- if (dc.ulval > 0)
- {
- /*
- * underline (.ul)
- *
- * Because of the way underlining is handled,
- * MAXLINE should be declared to be three times
- * larger than the longest expected input line
- * for underlining. Since many of the character
- * buffers use this parameter, a lot of memory
- * can be allocated when it may not really be
- * needed. A MAXLINE of 180 would allow about
- * 60 characters in the output line to be
- * underlined (remember that only alphanumerics
- * get underlined - no spaces or punctuation).
- */
- underl (p, wrdbuf, MAXLINE);
- --dc.ulval;
- }
- if (dc.cuval > 0)
- {
- /*
- * continuous underline (.cu)
- */
- underl (p, wrdbuf, MAXLINE);
- --dc.cuval;
- }
- if (dc.boval > 0)
- {
- /*
- * bold (.bo)
- */
- bold (p, wrdbuf, MAXLINE);
- --dc.boval;
- }
- if (dc.ceval > 0)
- {
- /*
- * centered (.ce)
- */
- center (p);
- do_mc (p);
- put (p);
- --dc.ceval;
- }
- else if ((*p == '\r' || *p == '\n') && dc.fill == NO)
- {
- /*
- * all blank line
- */
- do_mc (p);
- put (p);
- }
- else if (dc.fill == NO)
- {
- /*
- * unfilled (.nf)
- */
- do_mc (p);
- put (p);
- }
- else
- {
- /*
- * anything else...
- *
- * init escape char counter for this line...
- */
- /* co.outesc = 0;*/
-
-
- /*
- * get a word and put it out. increment ptr to the next
- * word.
- */
- while ((i = getwrd (p, wrdbuf)) > 0)
- {
- /* co.outesc += countesc (wrdbuf);*/
-
- putwrd (wrdbuf);
- p += i;
- }
- }
- }
-
-
-
-
- /*------------------------------*/
- /* bold */
- /*------------------------------*/
- bold (p0, p1, size)
- register char *p0;
- register char *p1;
- int size;
- {
-
- /*
- * insert bold face text (by overstriking)
- */
-
- register int i;
- register int j;
-
- j = 0;
- for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
- {
- if (isalpha (p0[i]) || isdigit (p0[i]))
- {
- p1[j++] = p0[i];
- p1[j++] = '\b';
- }
- p1[j++] = p0[i];
- }
- p1[j++] = '\n';
- p1[j] = EOS;
- while (*p1 != EOS)
- *p0++ = *p1++;
- *p0 = EOS;
- }
-
-
-
-
-
-
- /*------------------------------*/
- /* center */
- /*------------------------------*/
- center (p)
- register char *p;
- {
-
- /*
- * center a line by setting tival
- */
-
- dc.tival = max ((dc.rmval + dc.tival - width (p)) >> 1, 0);
- }
-
-
-
-
- /*------------------------------*/
- /* expand */
- /*------------------------------*/
- expand (p0, c, s)
- register char *p0;
- char c;
- register char *s;
- {
-
- /*
- * expand title buffer to include character string
- */
-
- register char *p;
- register char *q;
- register char *r;
- char tmp[MAXLINE];
-
- p = p0;
- q = tmp;
- while (*p != EOS)
- {
- if (*p == c)
- {
- r = s;
- while (*r != EOS)
- *q++ = *r++;
- }
- else
- *q++ = *p;
- ++p;
- }
- *q = EOS;
- strcpy (p0, tmp); /* copy it back */
- }
-
-
-
-
- /*------------------------------*/
- /* justcntr */
- /*------------------------------*/
- justcntr (p, q, limit)
- register char *p;
- char *q;
- int *limit;
- {
-
- /*
- * center title text into print buffer
- */
-
- register int len;
-
- len = width (p);
- q = &q[(limit[RIGHT] + limit[LEFT] - len) >> 1];
- while (*p != EOS)
- *q++ = *p++;
- }
-
-
-
-
-
- /*------------------------------*/
- /* justleft */
- /*------------------------------*/
- justleft (p, q, limit)
- register char *p;
- char *q;
- int limit;
- {
-
- /*
- * left justify title text into print buffer
- */
-
- q = &q[limit];
- while (*p != EOS)
- *q++ = *p++;
- }
-
-
-
-
- /*------------------------------*/
- /* justrite */
- /*------------------------------*/
- justrite (p, q, limit)
- register char *p;
- char *q;
- int limit;
- {
-
- /*
- * right justify title text into print buffer
- */
-
- register int len;
-
- len = width (p);
- q = &q[limit - len];
- while (*p != EOS)
- *q++ = *p++;
- }
-
-
-
-
-
-
- /*------------------------------*/
- /* leadbl */
- /*------------------------------*/
- leadbl (p)
- register char *p;
- {
-
- /*
- * delete leading blanks, set tival
- */
-
- register int i;
- register int j;
-
- /*
- * end current line and reset co struct
- */
- robrk ();
-
- /*
- * skip spaces
- */
- for (i = 0; p[i] == ' ' || p[i] == '\t'; ++i)
- ;
-
- /*
- * if not end of line, reset current temp indent
- */
- if (p[i] != '\n' && p[i] != '\r')
- dc.tival = i;
-
- /*
- * shift string
- */
- for (j = 0; p[i] != EOS; ++j)
- p[j] = p[i++];
- p[j] = EOS;
- }
-
-
-
-
-
- /*------------------------------*/
- /* pfoot */
- /*------------------------------*/
- pfoot ()
- {
-
- /*
- * put out page footer
- */
-
- if (dc.prflg == TRUE)
- {
- skip (pg.m3val);
- if (pg.m4val > 0)
- {
- if ((pg.curpag % 2) == 0)
- {
- puttl (pg.efoot, pg.eflim, pg.curpag);
- }
- else
- {
- puttl (pg.ofoot, pg.oflim, pg.curpag);
- }
- skip (pg.m4val - 1);
- }
- }
- }
-
-
-
-
-
- /*------------------------------*/
- /* phead */
- /*------------------------------*/
- phead ()
- {
-
- /*
- * put out page header
- */
-
- pg.curpag = pg.newpag;
- if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg)
- {
- dc.prflg = TRUE;
- }
- else
- {
- dc.prflg = FALSE;
- }
- ++pg.newpag;
- set_ireg ("%", pg.newpag, 0);
- if (dc.prflg == TRUE)
- {
- if (pg.m1val > 0)
- {
- skip (pg.m1val - 1);
- if ((pg.curpag % 2) == 0)
- {
- puttl (pg.ehead, pg.ehlim, pg.curpag);
- }
- else
- {
- puttl (pg.ohead, pg.ohlim, pg.curpag);
- }
- }
- skip (pg.m2val);
- }
- /*
- * initialize lineno for the next page
- */
- pg.lineno = pg.m1val + pg.m2val + 1;
- set_ireg ("ln", pg.lineno, 0);
- }
-
-
-
-
- /*------------------------------*/
- /* puttl */
- /*------------------------------*/
- puttl (p, lim, pgno)
- register char *p;
- int *lim;
- int pgno;
- {
-
- /*
- * put out title or footer
- */
-
- register int i;
- char pn[8];
- char t[MAXLINE];
- char h[MAXLINE];
- char delim;
-
- itoda (pgno, pn, 6);
- for (i = 0; i < MAXLINE; ++i)
- h[i] = ' ';
- delim = *p++;
- p = getfield (p, t, delim);
- expand (t, dc.pgchr, pn);
- justleft (t, h, lim[LEFT]);
- p = getfield (p, t, delim);
- expand (t, dc.pgchr, pn);
- justcntr (t, h, lim);
- p = getfield (p, t, delim);
- expand (t, dc.pgchr, pn);
- justrite (t, h, lim[RIGHT]);
- for (i = MAXLINE - 4; h[i] == ' '; --i)
- h[i] = EOS;
- h[++i] = '\n';
- #ifndef NOCR
- h[++i] = '\r';
- #endif
- h[++i] = EOS;
- if (strlen (h) > 2)
- {
- for (i = 0; i < pg.offset; ++i)
- prchar (' ', out_stream);
- }
- putlin (h, out_stream);
- }
-
-
-
-
-
- /*------------------------------*/
- /* putwrd */
- /*------------------------------*/
- putwrd (wrdbuf)
- register char *wrdbuf;
- {
-
- /*
- * put word in output buffer
- */
-
- register char *p0;
- register char *p1;
- int w;
- int last;
- int llval;
- int nextra;
-
-
-
- /*
- * check if this word puts us over the limit
- */
- w = width (wrdbuf);
- last = strlen (wrdbuf) + co.outp;
- llval = dc.rmval - dc.tival;
- /* if (((co.outp > 0) && ((co.outw + w) > llval))*/
- co.outesc += countesc (wrdbuf);
- if (((co.outp > 0) && ((co.outw + w - co.outesc) > llval))
- || (last > MAXLINE))
- {
- /*
- * last word exceeds limit so prepare to break line, print
- * it, and reset outbuf.
- */
- last -= co.outp;
- if (dc.juval == YES)
- {
- nextra = llval - co.outw + 1;
-
- /*
- * Do not take in the escape char of the
- * word that didn't fit on this line anymore
- */
- co.outesc -= countesc (wrdbuf);
-
- /*
- * Check whether last word was end of
- * sentence and modify counts so that
- * it is right justified.
- */
- if (co.outbuf[co.outp - 2] == ' ')
- {
- --co.outp;
- ++nextra;
- }
- #ifdef OLD_WAY
- spread (co.outbuf, co.outp - 1, nextra, co.outwds, co.outesc);
- if ((nextra > 0) && (co.outwds > 1))
- {
- co.outp += (nextra - 1);
- }
- /* if (co.outesc > 0)
- {
- co.outp += co.outesc;
- }
- */
- #else
- spread (co.outbuf, co.outp - 1, nextra,
- co.outwds, co.outesc);
- if ((nextra + co.outesc > 0) && (co.outwds > 1))
- {
- co.outp += (nextra + co.outesc - 1);
- }
- #endif
- }
-
- /*
- * break line, output it, and reset all co members. reset
- * esc count.
- */
- robrk ();
-
- co.outesc = countesc (wrdbuf);
- }
-
-
- /*
- * copy the current word to the out buffer which may have been
- * reset
- */
- p0 = wrdbuf;
- p1 = co.outbuf + co.outp;
- while (*p0 != EOS)
- *p1++ = *p0++;
-
- co.outp = last;
- co.outbuf[co.outp++] = ' ';
- co.outw += w + 1;
- co.outwds += 1;
- }
-
-
-
-
- /*------------------------------*/
- /* skip */
- /*------------------------------*/
- skip (n)
- register int n;
- {
-
- /*
- * skips the number of lines specified by n.
- */
-
- register int i;
- register int j;
-
-
- if (dc.prflg == TRUE && n > 0)
- {
- for (i = 0; i < n; ++i)
- {
- /*
- * handle blank line with changebar
- */
- if (mc_ing == TRUE)
- {
- for (j = 0; j < pg.offset; ++j)
- prchar (' ', out_stream);
- for (j = 0; j < dc.rmval; ++j)
- prchar (' ', out_stream);
- for (j = 0; j < mc_space; j++)
- prchar (' ', out_stream);
- prchar (mc_char, out_stream);
- }
- prchar ('\n', out_stream);
- #ifndef NOCR
- prchar ('\r', out_stream);
- #endif
- }
- }
- }
-
-
-
-
-
- /*------------------------------*/
- /* spread */
- /*------------------------------*/
- spread (p, outp, nextra, outwds, escapes)
- register char *p;
- int outp;
- int nextra;
- int outwds;
- int escapes;
- {
-
- /*
- * spread words to justify right margin
- */
-
- register int i;
- register int j;
- register int nb;
- register int ne;
- register int nholes;
- int jmin;
-
-
- /*
- * quick sanity check...
- */
- #ifdef OLDWAY
- if ((nextra <= 0) || (outwds <= 1))
- return;
- #else
- if ((nextra + escapes < 1) || (outwds < 2))
- return;
- #endif
-
-
- /*fflush (out_stream); fprintf (err_stream, "in spread: escapes = %d\n", escapes); fflush (err_stream);*/
-
-
- /*
- * set up for the spread and do it...
- */
- dc.sprdir = ~dc.sprdir;
- #ifdef OLD_WAY
- ne = nextra;
- #else
- ne = nextra + escapes;
- #endif
- nholes = outwds - 1; /* holes between words */
- i = outp - 1; /* last non-blank character */
- j = min (MAXLINE - 3, i + ne); /* leave room for CR,LF,EOS */
- /*
- j += escapes;
- if (p[i-1] == 27)
- j += 2;
- j = min (j, MAXLINE - 3);
- */
- while (i < j)
- {
- p[j] = p[i];
- if (p[i] == ' ')
- {
- if (dc.sprdir == 0)
- nb = (ne - 1) / nholes + 1;
- else
- nb = ne / nholes;
- ne -= nb;
- --nholes;
- for (; nb > 0; --nb)
- {
- --j;
- p[j] = ' ';
- }
- }
- --i;
- --j;
- }
- }
-
-
-
-
-
- /*------------------------------*/
- /* strkovr */
- /*------------------------------*/
- strkovr (p, q)
- register char *p;
- register char *q;
- {
-
- /*
- * split overstrikes (backspaces) into seperate buffer
- */
-
- register char *pp;
- int bsflg;
-
- bsflg = FALSE;
- pp = p;
- while (*p != EOS)
- {
- *q = ' ';
- *pp = *p;
- ++p;
- if (*p == '\b')
- {
- if (*pp >= ' ' && *pp <= '~')
- {
- bsflg = TRUE;
- *q = *pp;
- ++p;
- *pp = *p;
- ++p;
- }
- }
- ++q;
- ++pp;
- }
- *q++ = '\r';
- *q = *pp = EOS;
-
- return (bsflg);
- }
-
-
-
-
-
- /*------------------------------*/
- /* underl */
- /*------------------------------*/
- underl (p0, p1, size)
- register char *p0;
- register char *p1;
- int size;
- {
-
- /*
- * underline a line
- */
-
- register int i;
- register int j;
-
- j = 0;
- for (i = 0; (p0[i] != '\n') && (j < size - 1); ++i)
- {
- if (p0[i] >= ' ' && p0[i] <= '~')
- {
- if (isalpha (p0[i]) || isdigit (p0[i]) || dc.cuval > 0)
- {
- p1[j++] = '_';
- p1[j++] = '\b';
- }
- }
- p1[j++] = p0[i];
- }
- p1[j++] = '\n';
- p1[j] = EOS;
- while (*p1 != EOS)
- *p0++ = *p1++;
- *p0 = EOS;
- }
-
-
-
-
- /*------------------------------*/
- /* width */
- /*------------------------------*/
- width (s)
- register char *s;
- {
-
- /*
- * compute width of character string
- */
-
- register int w;
-
- w = 0;
- while (*s != EOS)
- {
- if (*s == '\b')
- --w;
- else if (*s != '\n' && *s != '\r')
- ++w;
- ++s;
- }
-
- return (w);
- }
-
-
-
-
- /*------------------------------*/
- /* do_mc */
- /*------------------------------*/
- do_mc (p)
- char *p;
- {
-
- /*
- * add margin char (change bar) for .nf and .ce lines.
- *
- * filled lines handled in robrk(). blank lines (.sp) handled in skip().
- * note: robrk() calls this routine, too.
- */
-
- register char *ps;
- register int nspaces;
- register int i;
- register int has_cr;
- register int has_lf;
- int len;
- int nesc;
-
-
- if (mc_ing == FALSE)
- return;
-
-
- len = strlen (p);
-
-
- /*
- * get to the end...
- */
- ps = p;
- while (*ps)
- ps++;
-
-
- /*
- * check for cr and lf
- */
- ps--;
- has_lf = 0;
- has_cr = 0;
- while (ps >= p && (*ps == '\r' || *ps == '\n'))
- {
- if (*ps == '\n')
- has_lf++;
- else
- has_cr++;
-
- len--;
- ps--;
- }
- if (has_lf < has_cr)
- has_lf = has_cr;
- else if (has_cr < has_lf)
- has_cr = has_lf;
-
-
- /*
- * remove any trailing blanks here
- */
- while (ps >= p && *ps == ' ')
- {
- ps--;
- len--;
- }
- *++ps = EOS;
-
-
- /*
- * add trailing spaces for short lines. count escapes, subtract
- * from len. use rmval for rigth margin (minus tival which is
- * added later in put).
- */
- nesc = countesc (p);
- len -= nesc;
- nspaces = dc.rmval - dc.tival - len;
- for (i = 0; i < nspaces; i++, ps++)
- *ps = ' ';
-
-
- /*
- * add the bar...
- */
- for (i = 0; i < mc_space; i++, ps++)
- *ps = ' ';
- *ps++ = mc_char;
-
-
- /*
- * replace cr, lf, and EOS
- */
- while (has_lf--)
- {
- *ps++ = '\r';
- *ps++ = '\n';
- }
- *ps = EOS;
-
-
- return;
- }
-